package com.coin900.coin.base.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.value.exception.BusinessException;
import org.w3c.dom.Document;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Hashtable;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * Unibon
 * <p/>
 * Copyright (c) 2012 YouPeng ValueSoft Inc., All rights reserved.
 * <p/>
 * This software is the confidential and proprietary information of
 * ValueSoft Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with ValueSoft.com.
 * <p/>
 * Revision History
 * Date      		Programmer       Notes
 * 2015/7/30   	     stone		     Initial
 * *********************************************************************
 */
public class FileUtils {
    public static File toFile(byte[] data, String filePath, String fileName) {
        if(data==null)return null;
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            file = new File(filePath + File.separator + fileName);
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(data);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.flush();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static byte[] zipFile(File file, String zipFileName) {
        File zipFile = new File(zipFileName);
        ZipOutputStream zos = null;
        OutputStream os=null;
        BufferedOutputStream bos=null;
        try {
            // 创建写出流操作
            os = new FileOutputStream(zipFile);
            bos = new BufferedOutputStream(os);
            zos = new ZipOutputStream(bos);
            String basePath = null;
            // 获取目录
            if (file.isDirectory()) {
                basePath = file.getPath();
            } else {
                basePath = file.getParent();
            }
            zipFile(file, basePath, zos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (zos != null) {
                    zos.flush();
                    zos.closeEntry();
                    zos.close();
                }
                bos.flush();
                bos.close();
                os.flush();
                os.close();


                //刪除原有文件
                FileUtils.deleteDir(file);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        byte[] buffer = null;
        ByteArrayOutputStream baos=null;
        FileInputStream fis=null;
        try {
            fis = new FileInputStream(zipFile);
            baos = new ByteArrayOutputStream(1024);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                baos.write(b, 0, n);
            }

            buffer = baos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(baos!=null) {
                    baos.flush();
                    baos.close();
                }
                if(fis!=null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            zipFile.delete();
        }

        return buffer;
    }

    /**
     * 打包
     *
     * @param source
     * @param basePath
     * @param zos
     * @throws IOException
     */
    public static void zipFile(File source, String basePath, ZipOutputStream zos)
            throws IOException {
        File[] files = null;
        if (source.isDirectory()) {
            files = source.listFiles();
        } else {
            files = new File[1];
            files[0] = source;
        }

        InputStream is = null;
        BufferedInputStream bis=null;
        String pathName;
        byte[] buf = new byte[1024];
        int length = 0;
        try {
            if (files.length > 0) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        pathName = file.getPath().substring(basePath.length() + 1) + "/";
                        zos.putNextEntry(new ZipEntry(pathName));
                        zipFile(file, basePath, zos);
                    } else {
                        pathName = file.getPath().substring(basePath.length() + 1);
                        is = new FileInputStream(file);
                        bis = new BufferedInputStream(is);
                        zos.putNextEntry(new ZipEntry(pathName));
                        while ((length = bis.read(buf)) > 0) {
                            zos.write(buf, 0, length);
                        }
                        if(bis!=null){
                            bis.close();
                        }
                        if (is != null) {
                            is.close();
                        }
                    }
                }
            } else {
                zos.putNextEntry(new ZipEntry(".tmp"));
            }
        } finally {
            if(bis!=null){
                bis.close();
            }
            if (is != null) {
                is.close();
            }
        }

    }
    public static boolean deleteDir(File dir) {
        if(!dir.exists())return true;
        if (dir.isDirectory()) {
            String[] children = dir.list();
           //递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }


    public static void downloadFile(String url, String outputPath) throws Exception {
        URL downUrl = new URL(url);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        InputStream is = null;
        try {
            is = downUrl.openStream();
            byte[] byteChunk = new byte[4096];
            int n;
            while ( (n = is.read(byteChunk)) > 0 ) {
                baos.write(byteChunk, 0, n);
            }
            byte[] bytes = baos.toByteArray();
            boolean b = FileUtils.toFile(outputPath, bytes);

            if(!b){
                throw new BusinessException("保存文件失败");
            }

        }catch (Exception e) {
            e.printStackTrace();
        } finally {
           inputStreamClose(is);
           outStreamClose(baos);
        }

    }



    public static boolean toFile(String filePath,byte[] data) {
        if(data==null)return false;
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file=new File(filePath);
        boolean isSuccess=false;
        try {
             if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(data);
            isSuccess=true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            outStreamClose(bos);
            outStreamClose(fos);
        }
        return isSuccess;
    }


    public static void inputStreamClose(InputStream stream){
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void outStreamClose(OutputStream stream){
        if (stream != null) {
            try {
                stream.flush();
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static void download(String sURL, String sName, String sPath) {
        int nStartPos = 0;
        int nRead = 0;
        try {
            URL url = new URL(sURL);
            //打开连接
            HttpURLConnection httpConnection = (HttpURLConnection) url
                    .openConnection();
            //获得文件长度
            long nEndPos = getFileSize(sURL);
            RandomAccessFile oSavedFile = new RandomAccessFile(sPath + File.separator + sName, "rw");
            httpConnection.setRequestProperty("User-Agent", "Internet Explorer");
            String sProperty = "bytes=" + nStartPos + "-";
            //告诉服务器book.rar这个文件从nStartPos字节开始传
            httpConnection.setRequestProperty("RANGE", sProperty);
            System.out.println(sProperty);
            InputStream input = httpConnection.getInputStream();
            byte[] b = new byte[1024];
            //读取网络文件,写入指定的文件中
            while ((nRead = input.read(b, 0, 1024)) > 0
                    && nStartPos < nEndPos) {
                oSavedFile.write(b, 0, nRead);
                nStartPos += nRead;
            }
            httpConnection.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static long getFileSize(String sURL) {
        int nFileLength = -1;
        try {
            URL url = new URL(sURL);
            HttpURLConnection httpConnection = (HttpURLConnection) url
                    .openConnection();
            httpConnection.setRequestProperty("User-Agent", "Internet Explorer");
            int responseCode = httpConnection.getResponseCode();
            if (responseCode >= 400) {
                System.err.println("Error Code : " + responseCode);
                return -2; // -2 represent access is error
            }
            String sHeader;
            for (int i = 1; ; i++) {
                sHeader = httpConnection.getHeaderFieldKey(i);
                if (sHeader != null) {
                    if (sHeader.equals("Content-Length")) {
                        nFileLength = Integer.parseInt(httpConnection
                                .getHeaderField(sHeader));
                        break;
                    }
                } else
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(nFileLength);
        return nFileLength;
    }




    public static byte[] toByteArray(String filename) throws IOException {
        File f = new File(filename);
        if (!f.exists()) {
            throw new FileNotFoundException(filename);
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            inputStreamClose(in);
            outStreamClose(bos);
        }
        return bos.toByteArray();
    }

    /**
     * 二维码编码
     *
     * @param contents
     * @param width
     * @param height
     */
    public static String encode(String contents, int width, int height) {
        Hashtable<Object, Object> hints = new Hashtable<Object, Object>();
        // 指定纠错等级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        // 指定编码格式
        String baseCode = "";
        try {
            BitMatrix byteMatrix;
            byteMatrix = new MultiFormatWriter().encode(new String(contents.getBytes("UTF-8"), "iso-8859-1"), BarcodeFormat.QR_CODE, width, height);
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(byteMatrix, "png", bao);
            baseCode = Base64Code(bao.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();

        }
        return baseCode;
    }

    public static String Base64Code(byte[] b) {
        BASE64Encoder encoder = new BASE64Encoder();
        String codeBase64 = "";
        StringBuilder pictureBuffer = new StringBuilder();
        pictureBuffer.append(encoder.encode(b));
        codeBase64 = pictureBuffer.toString();
        return codeBase64;
    }

    //base64字符串转化成图片
    public static byte[]  GenerateImage(String imgStr)
    {   //对字节数组字符串进行Base64解码并生成图片
        if (imgStr == null) //图像数据为空
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        try
        {
            //Base64解码
            byte[] b = decoder.decodeBuffer(imgStr);
            for(int i=0;i<b.length;++i)
            {
                if(b[i]<0)
                {//调整异常数据
                    b[i]+=256;
                }
            }
            //生成jpeg图片
            return b;
        }
        catch (Exception e)
        {
            return null;
        }
    }






    private static void output(Document doc, OutputStream out) throws Exception {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
                "-//W3C//DTD SVG 1.0//EN");
        transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
                "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd");
        transformer.transform(new DOMSource(doc), new StreamResult(out));
        out.flush();
        out.close();
    }




    //解压指定zip文件
    public static void unZip(String unZipfilePath,String outPath){
        FileOutputStream fileOut = null;
        File file;
        byte[] buf=new byte[1024];
        int readedBytes;
        FileInputStream fileInputStream=null;
        BufferedInputStream bufferedInputStream=null;
        ZipInputStream zipIn=null;

        try{
            File zipFile = new File(unZipfilePath);
            if(outPath==null){
                outPath = zipFile.getParent();
            }
            fileInputStream = new FileInputStream(unZipfilePath);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            zipIn = new ZipInputStream(bufferedInputStream);
            ZipEntry zipEntry;
            while((zipEntry = zipIn.getNextEntry()) != null){
                file = new File(outPath+System.getProperty("file.separator")+zipEntry.getName());
                if(zipEntry.isDirectory()){
                    file.mkdirs();
                } else{
                    //如果指定文件的目录不存在,则创建之.
                    File parent = file.getParentFile();
                    if(!parent.exists()){
                        parent.mkdirs();
                    }

                    fileOut = new FileOutputStream(file);
                    while(( readedBytes = zipIn.read(buf) ) > 0){
                        fileOut.write(buf , 0 , readedBytes );
                    }
                    fileOut.close();
                    zipEntry.clone();
                }
                zipIn.closeEntry();
            }
        }catch(IOException ioe){
            ioe.printStackTrace();
        }finally {
            inputStreamClose(zipIn);
            inputStreamClose(bufferedInputStream);
            inputStreamClose(fileInputStream);
            outStreamClose(fileOut);
        }
    }




    public static void main(String[] args) {
        FileUtils.unZip("/Users/zhangyou/html/res.zip","/Users/zhangyou/html");

        //判断是否存在





    }


}
